/**
 * 用户体验优化工具
 */
class UserExperience {
  constructor() {
    this.loadingStates = new Map() // 加载状态管理
    this.cacheData = new Map() // 数据缓存
    this.retryCounters = new Map() // 重试计数器
  }

  /**
   * 显示加载状态
   */
  showLoading(key, options = {}) {
    const defaultOptions = {
      title: '加载中...',
      mask: true,
      timeout: 10000 // 10秒超时
    }
    
    const config = { ...defaultOptions, ...options }
    
    // 设置加载状态
    this.loadingStates.set(key, {
      startTime: Date.now(),
      timeout: config.timeout
    })
    
    wx.showLoading({
      title: config.title,
      mask: config.mask
    })
    
    // 设置超时处理
    if (config.timeout > 0) {
      setTimeout(() => {
        if (this.loadingStates.has(key)) {
          this.hideLoading(key)
          wx.showToast({
            title: '请求超时，请重试',
            icon: 'none'
          })
        }
      }, config.timeout)
    }
  }

  /**
   * 隐藏加载状态
   */
  hideLoading(key) {
    if (this.loadingStates.has(key)) {
      this.loadingStates.delete(key)
      wx.hideLoading()
    }
  }

  /**
   * 检查加载状态
   */
  isLoading(key) {
    return this.loadingStates.has(key)
  }

  /**
   * 智能错误处理
   */
  handleError(error, context = '', options = {}) {
    console.error(`错误 [${context}]:`, error)
    
    const defaultOptions = {
      showToast: true,
      showModal: false,
      allowRetry: false,
      maxRetries: 3
    }
    
    const config = { ...defaultOptions, ...options }
    
    // 错误分类处理
    let message = '操作失败，请重试'
    let title = '提示'
    
    if (error.message) {
      if (error.message.includes('网络')) {
        message = '网络连接失败，请检查网络设置'
        title = '网络错误'
      } else if (error.message.includes('超时')) {
        message = '请求超时，请重试'
        title = '请求超时'
      } else if (error.message.includes('登录')) {
        message = '登录已过期，请重新登录'
        title = '登录过期'
      } else {
        message = error.message
      }
    }
    
    if (config.showModal) {
      const buttons = ['确定']
      
      // 如果允许重试且未达到最大重试次数
      if (config.allowRetry && this.canRetry(context, config.maxRetries)) {
        buttons.unshift('重试')
      }
      
      wx.showModal({
        title,
        content: message,
        showCancel: buttons.length > 1,
        cancelText: buttons[0],
        confirmText: buttons[buttons.length - 1],
        success: (res) => {
          if (res.cancel && config.allowRetry) {
            // 执行重试逻辑
            this.incrementRetry(context)
            if (config.onRetry) {
              config.onRetry()
            }
          }
        }
      })
    } else if (config.showToast) {
      wx.showToast({
        title: message,
        icon: 'none',
        duration: 3000
      })
    }
    
    return { message, title }
  }

  /**
   * 检查是否可以重试
   */
  canRetry(context, maxRetries) {
    const count = this.retryCounters.get(context) || 0
    return count < maxRetries
  }

  /**
   * 增加重试计数
   */
  incrementRetry(context) {
    const count = this.retryCounters.get(context) || 0
    this.retryCounters.set(context, count + 1)
  }

  /**
   * 重置重试计数
   */
  resetRetry(context) {
    this.retryCounters.delete(context)
  }

  /**
   * 数据缓存
   */
  setCache(key, data, options = {}) {
    const defaultOptions = {
      expire: 5 * 60 * 1000, // 5分钟过期
      syncToStorage: false
    }
    
    const config = { ...defaultOptions, ...options }
    
    const cacheItem = {
      data,
      timestamp: Date.now(),
      expire: config.expire
    }
    
    this.cacheData.set(key, cacheItem)
    
    // 同步到本地存储
    if (config.syncToStorage) {
      try {
        wx.setStorageSync(`cache_${key}`, cacheItem)
      } catch (error) {
        console.warn('缓存存储失败:', error)
      }
    }
  }

  /**
   * 获取缓存数据
   */
  getCache(key, options = {}) {
    const defaultOptions = {
      checkStorage: false
    }
    
    const config = { ...defaultOptions, ...options }
    
    // 优先从内存缓存获取
    let cacheItem = this.cacheData.get(key)
    
    // 如果内存中没有，尝试从本地存储获取
    if (!cacheItem && config.checkStorage) {
      try {
        cacheItem = wx.getStorageSync(`cache_${key}`)
        if (cacheItem) {
          this.cacheData.set(key, cacheItem)
        }
      } catch (error) {
        console.warn('读取缓存失败:', error)
      }
    }
    
    if (!cacheItem) {
      return null
    }
    
    // 检查是否过期
    const now = Date.now()
    if (now - cacheItem.timestamp > cacheItem.expire) {
      this.removeCache(key)
      return null
    }
    
    return cacheItem.data
  }

  /**
   * 移除缓存
   */
  removeCache(key) {
    this.cacheData.delete(key)
    try {
      wx.removeStorageSync(`cache_${key}`)
    } catch (error) {
      console.warn('删除缓存失败:', error)
    }
  }

  /**
   * 清空所有缓存
   */
  clearAllCache() {
    this.cacheData.clear()
    // 清空本地存储中的缓存
    try {
      const info = wx.getStorageInfoSync()
      const cacheKeys = info.keys.filter(key => key.startsWith('cache_'))
      cacheKeys.forEach(key => {
        wx.removeStorageSync(key)
      })
    } catch (error) {
      console.warn('清空缓存失败:', error)
    }
  }

  /**
   * 防抖处理
   */
  debounce(func, wait, immediate = false) {
    let timeout
    return function executedFunction(...args) {
      const later = () => {
        timeout = null
        if (!immediate) func.apply(this, args)
      }
      const callNow = immediate && !timeout
      clearTimeout(timeout)
      timeout = setTimeout(later, wait)
      if (callNow) func.apply(this, args)
    }
  }

  /**
   * 节流处理
   */
  throttle(func, limit) {
    let inThrottle
    return function(...args) {
      if (!inThrottle) {
        func.apply(this, args)
        inThrottle = true
        setTimeout(() => inThrottle = false, limit)
      }
    }
  }

  /**
   * 页面性能监控
   */
  startPerformanceMonitor(pageName) {
    const startTime = Date.now()
    
    return {
      end: () => {
        const loadTime = Date.now() - startTime
        console.log(`页面 [${pageName}] 加载时间: ${loadTime}ms`)
        
        // 如果加载时间过长，给出提示
        if (loadTime > 3000) {
          console.warn(`页面 [${pageName}] 加载时间过长: ${loadTime}ms`)
        }
        
        return loadTime
      }
    }
  }

  /**
   * 数据预加载
   */
  async preloadData(key, loadFunction, options = {}) {
    const defaultOptions = {
      force: false,
      background: true
    }
    
    const config = { ...defaultOptions, ...options }
    
    // 检查是否已有缓存
    if (!config.force) {
      const cached = this.getCache(key, { checkStorage: true })
      if (cached) {
        return cached
      }
    }
    
    try {
      const data = await loadFunction()
      this.setCache(key, data, { syncToStorage: true })
      return data
    } catch (error) {
      if (!config.background) {
        this.handleError(error, `预加载-${key}`)
      }
      throw error
    }
  }

  /**
   * 网络状态检查
   */
  checkNetworkStatus() {
    return new Promise((resolve) => {
      wx.getNetworkType({
        success: (res) => {
          const networkType = res.networkType
          const isConnected = networkType !== 'none'
          
          resolve({
            isConnected,
            networkType,
            isWifi: networkType === 'wifi',
            isMobile: ['2g', '3g', '4g', '5g'].includes(networkType)
          })
        },
        fail: () => {
          resolve({
            isConnected: false,
            networkType: 'unknown'
          })
        }
      })
    })
  }

  /**
   * 格式化文件大小
   */
  formatFileSize(bytes) {
    if (bytes === 0) return '0 B'
    
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
  }

  /**
   * 时间格式化
   */
  formatTime(timestamp, format = 'YYYY-MM-DD HH:mm:ss') {
    const date = new Date(timestamp)
    
    const formatMap = {
      'YYYY': date.getFullYear(),
      'MM': String(date.getMonth() + 1).padStart(2, '0'),
      'DD': String(date.getDate()).padStart(2, '0'),
      'HH': String(date.getHours()).padStart(2, '0'),
      'mm': String(date.getMinutes()).padStart(2, '0'),
      'ss': String(date.getSeconds()).padStart(2, '0')
    }
    
    let result = format
    Object.keys(formatMap).forEach(key => {
      result = result.replace(new RegExp(key, 'g'), formatMap[key])
    })
    
    return result
  }
}

// 创建全局实例
const ux = new UserExperience()

module.exports = {
  UserExperience,
  ux
} 